"""
数据分析API接口
提供人流量统计、热力图生成、趋势分析、报表生成等功能的REST API
"""
from datetime import datetime, date, timedelta
from typing import List, Dict, Optional, Any
from fastapi import APIRouter, HTTPException, Depends, Query, BackgroundTasks
from fastapi.responses import FileResponse
import logging

from services.data_analysis_service import get_data_analysis_service, DataAnalysisService
from schemas.data_analysis import (
    TimeSeries, StatisticalSummary, HeatmapData, TrendAnalysis,
    ChartData, ChartConfig, Report, DataQuery, Dashboard,
    TimeGranularity, ChartType, AggregationType, ReportType,
    PerformanceMetrics, ExportConfig
)
from core.config import get_settings

logger = logging.getLogger(__name__)
settings = get_settings()

router = APIRouter()


@router.get("/statistics/person-count", response_model=TimeSeries)
async def get_person_count_statistics(
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    granularity: TimeGranularity = Query(TimeGranularity.HOUR, description="时间粒度"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取人员数量统计"""
    try:
        return await service.get_person_count_statistics(
            start_time, end_time, camera_id, granularity
        )
    except Exception as e:
        logger.error(f"Error getting person count statistics: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/statistics/summary", response_model=StatisticalSummary)
async def get_statistical_summary(
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    metric: str = Query("total_count", description="指标名称"),
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取统计摘要"""
    try:
        return await service.get_statistical_summary(
            start_time, end_time, metric, camera_id
        )
    except Exception as e:
        logger.error(f"Error getting statistical summary: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/heatmap/{camera_id}", response_model=HeatmapData)
async def generate_heatmap(
    camera_id: str,
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    width: int = Query(640, description="图像宽度"),
    height: int = Query(480, description="图像高度"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """生成热力图"""
    try:
        return await service.generate_heatmap(
            camera_id, start_time, end_time, width, height
        )
    except Exception as e:
        logger.error(f"Error generating heatmap: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/heatmap/{camera_id}/hotspots")
async def get_heatmap_hotspots(
    camera_id: str,
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取热点区域"""
    try:
        return await service.get_heatmap_hotspots(camera_id, start_time, end_time)
    except Exception as e:
        logger.error(f"Error getting heatmap hotspots: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/trend-analysis", response_model=TrendAnalysis)
async def analyze_trend(
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    metric: str = Query("total_count", description="指标名称"),
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    granularity: TimeGranularity = Query(TimeGranularity.HOUR, description="时间粒度"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """分析趋势"""
    try:
        return await service.analyze_trend(
            start_time, end_time, metric, camera_id, granularity
        )
    except Exception as e:
        logger.error(f"Error analyzing trend: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/anomalies")
async def detect_anomalies(
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    metric: str = Query("total_count", description="指标名称"),
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    threshold: float = Query(2.0, description="异常阈值"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """检测异常值"""
    try:
        return await service.detect_anomalies(
            start_time, end_time, metric, camera_id, threshold
        )
    except Exception as e:
        logger.error(f"Error detecting anomalies: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/charts", response_model=ChartData)
async def create_chart(
    chart_config: ChartConfig,
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    metrics: Optional[List[str]] = Query(None, description="指标列表"),
    camera_ids: Optional[List[str]] = Query(None, description="摄像头ID列表"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """创建图表"""
    try:
        return await service.create_chart(
            chart_config, start_time, end_time, metrics, camera_ids
        )
    except Exception as e:
        logger.error(f"Error creating chart: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/charts/{chart_id}", response_model=ChartData)
async def get_chart(
    chart_id: str,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取图表"""
    try:
        chart = await service.get_chart(chart_id)
        if not chart:
            raise HTTPException(status_code=404, detail="Chart not found")
        return chart
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting chart: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/charts/{chart_id}", response_model=ChartData)
async def update_chart(
    chart_id: str,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """更新图表数据"""
    try:
        chart = await service.update_chart(chart_id)
        if not chart:
            raise HTTPException(status_code=404, detail="Chart not found")
        return chart
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error updating chart: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/reports", response_model=Report)
async def generate_report(
    report_type: ReportType,
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    title: Optional[str] = Query(None, description="报告标题"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """生成报告"""
    try:
        return await service.generate_report(report_type, start_time, end_time, title)
    except Exception as e:
        logger.error(f"Error generating report: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/reports/{report_id}", response_model=Report)
async def get_report(
    report_id: str,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取报告"""
    try:
        report = await service.get_report(report_id)
        if not report:
            raise HTTPException(status_code=404, detail="Report not found")
        return report
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting report: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/reports/daily/{date}", response_model=Report)
async def get_daily_report(
    date: date,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取日报"""
    try:
        return await service.get_daily_report(date)
    except Exception as e:
        logger.error(f"Error getting daily report: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/reports/weekly/{year}/{week}", response_model=Report)
async def get_weekly_report(
    year: int,
    week: int,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取周报"""
    try:
        return await service.get_weekly_report(year, week)
    except Exception as e:
        logger.error(f"Error getting weekly report: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/reports/monthly/{year}/{month}", response_model=Report)
async def get_monthly_report(
    year: int,
    month: int,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取月报"""
    try:
        return await service.get_monthly_report(year, month)
    except Exception as e:
        logger.error(f"Error getting monthly report: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/dashboards", response_model=Dashboard)
async def create_dashboard(
    dashboard: Dashboard,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """创建仪表板"""
    try:
        return await service.create_dashboard(dashboard)
    except Exception as e:
        logger.error(f"Error creating dashboard: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/dashboards/{dashboard_id}", response_model=Dashboard)
async def get_dashboard(
    dashboard_id: str,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取仪表板"""
    try:
        dashboard = await service.get_dashboard(dashboard_id)
        if not dashboard:
            raise HTTPException(status_code=404, detail="Dashboard not found")
        return dashboard
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error getting dashboard: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.put("/dashboards/{dashboard_id}", response_model=Dashboard)
async def update_dashboard(
    dashboard_id: str,
    dashboard: Dashboard,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """更新仪表板"""
    try:
        updated_dashboard = await service.update_dashboard(dashboard_id, dashboard)
        if not updated_dashboard:
            raise HTTPException(status_code=404, detail="Dashboard not found")
        return updated_dashboard
    except HTTPException:
        raise
    except Exception as e:
        logger.error(f"Error updating dashboard: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/query")
async def query_data(
    query: DataQuery,
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """查询数据"""
    try:
        return await service.query_data(query)
    except Exception as e:
        logger.error(f"Error querying data: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/real-time/stats")
async def get_real_time_stats(
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取实时统计"""
    try:
        return await service.get_real_time_stats()
    except Exception as e:
        logger.error(f"Error getting real-time stats: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/real-time/person-count")
async def get_current_person_count(
    camera_id: Optional[str] = Query(None, description="摄像头ID"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取当前人员数量"""
    try:
        count = await service.get_current_person_count(camera_id)
        return {"camera_id": camera_id, "person_count": count, "timestamp": datetime.now()}
    except Exception as e:
        logger.error(f"Error getting current person count: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/real-time/alert-summary")
async def get_alert_summary(
    hours: int = Query(24, description="统计时间范围(小时)"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取告警摘要"""
    try:
        return await service.get_alert_summary(hours)
    except Exception as e:
        logger.error(f"Error getting alert summary: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/export")
async def export_data(
    start_time: datetime = Query(..., description="开始时间"),
    end_time: datetime = Query(..., description="结束时间"),
    data_types: List[str] = Query(..., description="数据类型列表"),
    export_config: ExportConfig = ...,
    background_tasks: BackgroundTasks = BackgroundTasks(),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """导出数据"""
    try:
        export_path = await service.export_data(
            start_time, end_time, data_types, export_config
        )
        
        # 添加后台任务清理临时文件
        background_tasks.add_task(cleanup_export_file, export_path)
        
        return FileResponse(
            export_path,
            media_type='application/octet-stream',
            filename=export_path.split('/')[-1]
        )
    except Exception as e:
        logger.error(f"Error exporting data: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.get("/performance/metrics")
async def get_performance_metrics(
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """获取性能指标"""
    try:
        return await service.get_performance_metrics()
    except Exception as e:
        logger.error(f"Error getting performance metrics: {e}")
        raise HTTPException(status_code=500, detail=str(e))


@router.post("/performance/metrics")
async def add_performance_metric(
    name: str = Query(..., description="指标名称"),
    value: float = Query(..., description="指标值"),
    unit: Optional[str] = Query(None, description="单位"),
    tags: Optional[Dict[str, str]] = Query(None, description="标签"),
    service: DataAnalysisService = Depends(get_data_analysis_service)
):
    """添加性能指标"""
    try:
        await service.add_performance_metric(name, value, unit, tags)
        return {"message": "Performance metric added successfully"}
    except Exception as e:
        logger.error(f"Error adding performance metric: {e}")
        raise HTTPException(status_code=500, detail=str(e))


async def cleanup_export_file(file_path: str):
    """清理导出文件"""
    try:
        import os
        import asyncio
        # 等待5分钟后删除文件
        await asyncio.sleep(300)
        if os.path.exists(file_path):
            os.remove(file_path)
            logger.info(f"Cleaned up export file: {file_path}")
    except Exception as e:
        logger.error(f"Error cleaning up export file {file_path}: {e}")


# 健康检查
@router.get("/health")
async def health_check():
    """健康检查"""
    return {
        "status": "healthy",
        "service": "data_analysis",
        "timestamp": datetime.now()
    }